using System.ComponentModel;
using Godot;

namespace RoboRampage.Player;

public partial class Player : CharacterBody3D
{
    // 最大生命上限
    [Export] public float ExMaxHitpoints = 100f;

    // 定义玩家的速度和跳跃速度
    [Export] public float ExSpeed = 5.0f; // 玩家的移动速度

    [Export] public float ExJumpHeight = 1f; // 玩家的跳跃速度

    [Export] public float ExFallMultiplier = 2.5f; // 下坠的乘数效应

    [Export] [Description("镜头跟随鼠标移动的速度")] public float ExCameraFollowsSpeed = 0.002f; // 镜头跟随鼠标移动的速度

    [Export] public float ExAimMultiplier = 0.7f; // 瞄准时的视野倍数，0.7：表示原视角大小的0.7倍（缩小视角了）

    // 定义玩家的鼠标XZ轴移动的坐标
    private Vector2 _mouseMotion = Vector2.Zero;

    private Node3D _cameraPivot; // 相机节点
    private AnimationPlayer _damageAnimationPlayer; // 受伤动画播放器
    private GameOverMenu _gameOverMenu; // 游戏结束菜单
    private Camera3D _smoothCamera3D; // 平滑相机
    private Camera3D _weaponCamera; // 武器相机
    private float _smoothCamera3DFov; // 平滑相机初始视野
    private float _weaponCameraFov; // 武器相机初始视野
    public AmmonHandler InAmmonHandler; // 弹药处理器

    private float _currHitpoints; // 私有字段存储实际值

    // 当前生命值
    public float CurrHitpoints
    {
        get => _currHitpoints;
        set
        {
            // 新值小于当前生命值（受伤），则播放受伤动画
            if (value < _currHitpoints)
            {
                // 复位
                _damageAnimationPlayer.Stop();

                _damageAnimationPlayer.Play("TakeDamage");
            }

            _currHitpoints = value;
            // 生命值掉完了就删除组件
            if (value <= 0) _gameOverMenu.GameOver();
        }
    }

    public override void _Ready()
    {
        CurrHitpoints = ExMaxHitpoints;
        _cameraPivot = (Node3D)GetNode("CameraPivot");
        _damageAnimationPlayer = (AnimationPlayer)GetNode("DamageTextureRect/DamageAnimationPlayer");
        _gameOverMenu = (GameOverMenu)GetNode("GameOverMenu");
        InAmmonHandler = GetNode<AmmonHandler>("%AmmonHandler");
        _smoothCamera3D = GetNode<Camera3D>("%SmoothCamera3D");
        _weaponCamera = GetNode<Camera3D>("%WeaponCamera");
        _smoothCamera3DFov = _smoothCamera3D.Fov;
        _weaponCameraFov = _weaponCamera.Fov;
        // 设置鼠标模式为捕获模式
        Input.MouseMode = Input.MouseModeEnum.Captured;
    }

// 定义一个重写的方法 _Process，用于处理每一帧的逻辑更新
    public override void _Process(double delta)
    {
        // 检查是否按下了 "aim" 动作（鼠标右键）
        // 如果 "aim" 动作被按下，则调整相机视野 (Field of View, FOV)
        // 将相机的视野设置为原始视野乘以一个额外的瞄准倍数（拉近聚焦精准射击）
        if (Input.IsActionPressed("aim"))
        {
            _smoothCamera3D.Fov =
                (float)Mathf.Lerp(_smoothCamera3D.Fov, _smoothCamera3DFov * ExAimMultiplier, delta * 20.0f);
            _weaponCamera.Fov = (float)Mathf.Lerp(_weaponCamera.Fov, _weaponCameraFov * ExAimMultiplier, delta * 20.0f);
            // GD.Print("_smoothCamera3D:", _smoothCamera3D.Fov);
            // GD.Print("_weaponCamera:", _weaponCamera.Fov);
        }
        else
        {
            _smoothCamera3D.Fov = (float)Mathf.Lerp(_smoothCamera3D.Fov, _smoothCamera3DFov, delta * 30.0f);
            _weaponCamera.Fov = (float)Mathf.Lerp(_weaponCamera.Fov, _weaponCameraFov, delta * 30.0f);
        }
    }

    // 重写父类的物理过程方法
    public override void _PhysicsProcess(double delta)
    {
        // 处理相机旋转
        HandleCameraRotation();
        // 获取当前速度
        Vector3 velocity = Velocity;

        // 如果没有接触地板，则下坠
        if (!IsOnFloor())
        {
            // 重力值默认9.8
            // velocity += GetGravity() * (float)delta;
            if (velocity.Y >= 0)
            {
                velocity.Y -= -GetGravity().Y * (float)delta;
            }
            else
            {
                // 如果玩家不在地面上，根据重力值GetGravity()更新速度向量velocity，模拟重力效果。
                velocity.Y -= -GetGravity().Y * (float)delta * ExFallMultiplier;
            }
        }

        // 处理跳跃
        if (Input.IsActionJustPressed("jump") && IsOnFloor())
        {
            // 最大高度=速度的平方除以2g
            var jumpHeight = ExJumpHeight * 2.0f * -GetGravity().Y;
            GD.Print("jumpHeight:>>>", jumpHeight);
            velocity.Y = jumpHeight < 0 ? 0 : Mathf.Sqrt(jumpHeight);
        }

        // 获取输入方向并处理移动/减速
        // 良好的实践是使用自定义的游戏操作而不是UI操作
        Vector2 inputDir = Input.GetVector("move_left", "move_right", "move_forward", "move_back");
        Vector3 direction = (Transform.Basis * new Vector3(inputDir.X, 0, inputDir.Y)).Normalized();
        if (direction != Vector3.Zero)
        {
            velocity.X = direction.X * ExSpeed;
            velocity.Z = direction.Z * ExSpeed;
            if (Input.IsActionPressed("aim"))
            {
                velocity.X *= ExAimMultiplier;
                velocity.Z *= ExAimMultiplier;
            }
        }
        else
        {
            velocity.X = Mathf.MoveToward(Velocity.X, 0, ExSpeed);
            velocity.Z = Mathf.MoveToward(Velocity.Z, 0, ExSpeed);
        }

        Velocity = velocity;
        MoveAndSlide();
    }

    public override void _Input(InputEvent @event)
    {
        // 鼠标可以让物体左右移动
        // InputEventMouseMotion 表示鼠标或笔的移动
        if (@event is InputEventMouseMotion mouseMotionEvent)
        {
            // 如果鼠标模式为捕获模式（隐藏模式）
            if (Input.MouseMode == Input.MouseModeEnum.Captured)
                // 将鼠标或笔的移动量Relative转换为浮点数，并乘以0.002
                _mouseMotion = -mouseMotionEvent.Relative * ExCameraFollowsSpeed;
            if (@event.IsActionPressed("aim"))
            {
                _mouseMotion *= ExAimMultiplier;
            }
        }

        // Esc键
        if (Input.IsActionJustPressed("ui_cancel"))
        {
            // 将鼠标模式设置为可见
            Input.MouseMode = Input.MouseMode == Input.MouseModeEnum.Visible
                ? Input.MouseModeEnum.Captured
                : Input.MouseModeEnum.Visible;
        }
    }

    // 处理相机旋转
    public void HandleCameraRotation()
    {
        // 视角左右移动，根据鼠标移动量旋转相机
        RotateY(_mouseMotion.X);
        // 视角上下移动
        _cameraPivot.RotateX(_mouseMotion.Y);
        _cameraPivot.RotationDegrees = new Vector3(Mathf.Clamp(_cameraPivot.RotationDegrees.X, -89, 89),
            _cameraPivot.RotationDegrees.Y, _cameraPivot.RotationDegrees.Z);
        // 重置鼠标移动量
        _mouseMotion = Vector2.Zero;
    }
}